package com.stlm2.util;

import net.spy.memcached.AddrUtil;
import net.spy.memcached.BinaryConnectionFactory;
import net.spy.memcached.ConnectionFactoryBuilder;
import net.spy.memcached.ConnectionFactoryBuilder.Protocol;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.auth.AuthDescriptor;
import net.spy.memcached.auth.PlainCallbackHandler;
import net.spy.memcached.internal.OperationFuture;
import org.apache.ibatis.cache.CacheException;

import java.io.IOException;
import java.io.Serializable;
import java.util.concurrent.ExecutionException;


public class Memcached {
    private String host;
    private String port;
    private String username;
    private String password;
    private MemcachedClient cache=null;

    public String getHost() {
        return host;
    }

    public void setHost(String host) {
        this.host = host;
    }

    public String getPort() {
        return port;
    }

    public void setPort(String port) {
        this.port = port;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }


    public Object get(String key) {
        Object object=null;
        try {
             object=  getCache().get(key);
        }catch (Exception e){

        }
        return  object;
    }

    public boolean delete(String key) {
        OperationFuture<Boolean> future=getCache().delete(key);
        try {
            future.get();
        } catch (InterruptedException e) {
            if (cache != null) {
                cache.shutdown();
                cache=null;
            }
            return false;
        } catch (ExecutionException e) {
            if (cache != null) {
                cache.shutdown();
                cache=null;
            }
            return false;
        }
        return true;
    }

    public boolean set(String key, int expires_in, Object value) {
        if (value != null && !Serializable.class.isAssignableFrom(value.getClass())) {
            throw new CacheException("Object of type '"
                    + value.getClass().getName()
                    + "' that's non-serializable is not supported by Memcached");
        }
        OperationFuture<Boolean> future = getCache().set(key, expires_in, value);
        try {
            future.get();
        } catch (InterruptedException e) {
            if (cache != null) {
                cache.shutdown();
                cache=null;
            }
            return false;
        } catch (ExecutionException e) {
            if (cache != null) {
                cache.shutdown();
                cache=null;
            }
            return false;
        }
        return true;
    }

    public MemcachedClient getCache() {

        if (cache == null) {

            if(this.getUsername()==null||this.getUsername().equals("")){
                try {
                    cache = new MemcachedClient(new BinaryConnectionFactory(), AddrUtil.getAddresses(host + ":" + port));
                } catch (IOException e) {
                    e.printStackTrace();
                }

            }else{
                AuthDescriptor ad = new AuthDescriptor(new String[] { "PLAIN" },
                        new PlainCallbackHandler(username, password));
                try {
                    cache = new MemcachedClient(new ConnectionFactoryBuilder()
                            .setProtocol(Protocol.BINARY).setAuthDescriptor(ad)
                            .build(), AddrUtil.getAddresses(host + ":" + port));
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

            }




        return cache;
    }


}
